home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / osi / isode / dosisode / DOSISODE-RUNTIME.ZIP / SOCKETS / SOCKETS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-12  |  8.4 KB  |  367 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include <alloc.h>
  4. #include <mem.h>
  5. #include <time.h>
  6. #include "si_ip.h"
  7. #include "errno.h"
  8. #include "wattcp.h"
  9.  
  10. #define ATTR 0x7900
  11. #define HI(a)    ((a & 0xff00) >> 8)
  12. #define LO(a)    (a & 0x00ff)
  13. #define MAX_SOCK 6
  14. #define SOCK_STREAM 1
  15. #define SOCK_DGRAM 2
  16. #define ntohl(x) (( (((unsigned long) x) >> 24)& 0x000000ff ) |\
  17.                   ( (((unsigned long) x) >> 8) & 0x0000ff00 ) |\
  18.                   ( (((unsigned long) x) << 8) & 0x00ff0000 ) |\
  19.                   ( (((unsigned long) x) << 24)& 0xff000000 ))
  20. #define ntohs(x) (( (((unsigned short) x) >> 8) |\
  21.           ( (((unsigned short) x) << 8)) & 0xffff ))
  22. #define htonl(x) (( (((unsigned long) x) >> 24)& 0x000000ff ) |\
  23.                   ( (((unsigned long) x) >> 8) & 0x0000ff00 ) |\
  24.                   ( (((unsigned long) x) << 8) & 0x00ff0000 ) |\
  25.                   ( (((unsigned long) x) << 24)& 0xff000000 ))
  26. #define htons(x) (( (((unsigned short) x) >> 8) |\
  27.           ( (((unsigned short) x) << 8)) & 0xffff ))
  28.  
  29. #define FD_SET(f,l) (l |= (1<<(f)))
  30. #define FD_CLR(f,l) (l &= ~(1<<(f)))
  31. #define FD_ISSET(f,l) (l & (1<<(f)))
  32. #define FD_ZERO(l) (l = 0)
  33.  
  34. /*extern unsigned _heaplen = 0x0600;
  35. extern unsigned _stklen = 0x0200;*/
  36.  
  37. void interrupt (*oldhandler)(void);
  38. sock_type *look_up();
  39. sock_type *new_array();
  40. sock_type *remove_array();
  41.  
  42. int sock_table[MAX_SOCK] = {0,0,0,0,0,0};
  43. sock_type sock[MAX_SOCK];
  44. char dos_buffer[4500]; /*transfer array*/
  45. struct {
  46.     int type;
  47.     struct {
  48.         unsigned non_block :1;
  49.         unsigned is_connected :1;
  50.         unsigned non_block_failed :1;
  51.     } bit;
  52. } __sock[32];
  53. unsigned long host;
  54. struct rsockaddr {
  55.     int s_family;
  56.     int s_port;
  57.     longword s_ip;
  58.     char zero[8];
  59. };
  60.  
  61. static unsigned int fd;
  62. static int total, nfds, timeout;
  63. static long readfds,writefds,exceptfds;
  64. static long new_readfds,new_writefds,new_exceptfds;
  65. static time_t end;
  66. static time_t now;
  67. static int debug = 0;
  68.  
  69. void interrupt handler(bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags)
  70. unsigned bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags;
  71. {
  72.     static sock_type *s;
  73.     static struct rsockaddr *q;
  74.     static int init = 0, status;
  75.  
  76.     enable();
  77.     switch (ax) {
  78.     case 0x0000:
  79.     case 0x0100:
  80.     case 0x0200:
  81.         _AX = ax;
  82.         _DX = dx;
  83.         (*oldhandler)();
  84.     case SI_SOCKET:
  85. if (debug) printf("socket called\n");
  86.         if (!init) {
  87.             sock_init();
  88.             tcp_cbrk(0x01);
  89.             init=1;
  90.         }
  91.         s = new_array(dx, cx);
  92.         ax = (s == NULL) ? FAIL : SUCCESS;
  93.         if (ax == FAIL) {
  94.             cx = ENFILE;
  95.             return;
  96.         }
  97.         __sock[dx].type = cx;
  98.         cx = FP_SEG(dos_buffer);
  99.         dx = FP_OFF(dos_buffer);
  100.         return;
  101.     case SI_BIND:
  102.         return;
  103.     case SI_CONNECT:
  104. if (debug) printf("connect called\n");
  105.         s = look_up(dx);
  106.         if (s == NULL) {
  107.             ax = FAIL;
  108.             cx = EINVAL;
  109.         }
  110.         if (__sock[dx].bit.is_connected) {
  111.             cx = EISCONN;
  112.             ax = FAIL;
  113.             return;
  114.         };
  115.         if (tcp_established(s)) {
  116.             cx = EISCONN;
  117.             ax = FAIL;
  118.             return;
  119.         }
  120.         if (__sock[dx].bit.non_block_failed) {
  121.             __sock[dx].bit.non_block_failed = 0;
  122.             cx = ECONNREFUSED;
  123.             ax = FAIL;
  124.             return;
  125.         }
  126.         q = (struct rsockaddr *)dos_buffer;
  127.         status = tcp_open(s, 0, ntohl(q->s_ip), ntohs(q->s_port),NULL);
  128. if (debug) printf("tcp connecting to %lx %x returns %d\n",ntohl(q->s_ip),ntohs(q->s_port),status);
  129.  
  130.         if (__sock[dx].bit.non_block) {
  131.             ip_timer_init(s, sock_delay);
  132.             cx = EINPROGRESS;
  133.             ax = FAIL;
  134.             return;
  135.         };
  136. if (debug) printf("connect waiting\n");
  137.         sock_wait_established(s, sock_delay, NULL, &status);
  138. if (debug) printf("connected\n");
  139.         __sock[dx].bit.is_connected = 1;
  140.         ax = SUCCESS;
  141.         return;
  142. sock_err:
  143. if (debug) printf("connect failed\n");
  144.         cx = ECONNREFUSED;
  145.         ax = FAIL;
  146.         return;
  147.     case SI_LISTEN:
  148.         return;
  149.     case SI_ACCEPT:
  150.         return;
  151.     case SI_RECVFROM:
  152. if (debug) printf("recvfrom called\n");
  153.         s = look_up(dx);
  154.         if (__sock[dx].type == SOCK_STREAM) {
  155.             if (!tcp_established(s)) {
  156.                 cx = EBADF;
  157.                 ax = FAIL;
  158.                 return;
  159.             }
  160.         }
  161.         if (__sock[dx].bit.non_block_failed) {
  162.             __sock[dx].bit.non_block_failed = 0;
  163.             cx = ECONNREFUSED;
  164.             ax = FAIL;
  165.             return;
  166.         }
  167.  
  168.         tcp_tick(s);
  169.         if (__sock[dx].bit.non_block && ! sock_dataready(s)) {
  170.             cx = EWOULDBLOCK;
  171.             ax = FAIL;
  172.             return;
  173.         };
  174.         while (! sock_dataready(s)) tcp_tick(s);
  175.         ax = sock_fastread(s, dos_buffer+16, cx);
  176.         memcpy(dos_buffer+2,(char *)(htons(((tcp_Socket *)s)->hisport)),2);
  177.         memcpy(dos_buffer+4,(char *)(htonl(((tcp_Socket *)s)->hisaddr)),4);
  178.         cx = 0;
  179.         return;
  180.     case SI_SENDTO:
  181. if (debug) printf("sendto called\n");
  182.         s = look_up(dx);
  183.         if (__sock[dx].type == SOCK_STREAM) {
  184.             if (!tcp_established(s)) {
  185.                 cx = EBADF;
  186.                 ax = FAIL;
  187.                 return;
  188.             }
  189.         }
  190.         else {
  191.             sock_close(s);
  192.             q = (struct rsockaddr *)dos_buffer;
  193.             status = udp_open(s, 0, ntohl(q->s_ip), ntohs(q->s_port),NULL);
  194. if (debug) printf("udp connecting to %lx %x returns %d\n",ntohl(q->s_ip),ntohs(q->s_port),status);
  195.         }
  196.         sock_write(s,dos_buffer+16,cx);
  197.         sock_flush(s);
  198.         ax = cx;
  199.         cx = 0;
  200.         return;
  201.     case SI_SELECT:
  202.         nfds = dx;
  203.         memcpy(&readfds,dos_buffer,4);
  204.         memcpy(&writefds,dos_buffer+4,4);
  205.         memcpy(&exceptfds,dos_buffer+8,4);
  206.         memcpy(&timeout,dos_buffer+12,2);
  207.         if (timeout != -1) {
  208.             if (timeout != 0) {
  209.                 time(&now);
  210.                 end = now + timeout;
  211.             }
  212.             else end = 0;
  213.         }
  214.         else end = -1;
  215.         total = 0;
  216.         FD_ZERO(new_readfds);
  217.         FD_ZERO(new_writefds);
  218.         FD_ZERO(new_exceptfds);
  219.         do {
  220.             for (fd = 0; fd<MAX_SOCK; fd++) {
  221.                 s = look_up(fd);
  222.                 if (s) tcp_tick(s);
  223.             }
  224.  
  225.             for (fd = 1; fd <nfds; fd++) {
  226.                 s = look_up(fd);
  227.                 if (FD_ISSET(fd, writefds)) {
  228.                     if (!s || (s && tcp_established(s))) {
  229.                         __sock[fd].bit.is_connected = 1;
  230.                         FD_SET(fd, new_writefds);
  231.                         total++;
  232.                     }
  233.                     if (s && !tcp_established(s)) {
  234.                         if (!s->tcp.ip_type || ip_timer_expired(s)) {
  235.                             FD_SET(fd, new_writefds);
  236.                             total++;
  237.                             sock_close(s);
  238.                             __sock[fd].bit.non_block_failed = 1;
  239.                         }
  240.                         else if (__sock[fd].bit.non_block_failed) {
  241.                             FD_SET(fd, new_writefds);
  242.                             total++;
  243.                         }
  244.                     }
  245.                 }
  246.             }
  247.  
  248.             if (FD_ISSET(0,readfds) && kbhit()) {
  249.                 FD_SET(fd, new_readfds);
  250.                 total++;
  251.             }
  252.             for (fd = 3; fd <nfds; fd++) {
  253.                 if (FD_ISSET(fd, readfds)) {
  254.                     s = look_up(fd);
  255.                     if (!s || (s && unreaddata(s))) {
  256.                         __sock[fd].bit.is_connected = 1;
  257.                         FD_SET(fd, new_readfds);
  258.                         total++;
  259.                     }
  260.                     if (s && !tcp_established(s)) {
  261.                         if (!s->tcp.ip_type || ip_timer_expired(s)) {
  262.                             FD_SET(fd, new_readfds);
  263.                             total++;
  264.                             sock_close(s);
  265.                             __sock[fd].bit.non_block_failed = 1;
  266.                         }
  267.                         else if (__sock[fd].bit.non_block_failed) {
  268.                             FD_SET(fd, new_readfds);
  269.                             total++;
  270.                         }
  271.                     }
  272.                 }
  273.             }
  274.             if (end == 0) break;
  275.             if (total) break;
  276.             time(&now);
  277.         } while (now < end);
  278.         if (readfds) memcpy(dos_buffer,&new_readfds,4);
  279.         if (writefds) memcpy(dos_buffer+4,&new_writefds,4);
  280.         if (exceptfds) memcpy(dos_buffer+8,&new_exceptfds,4);
  281.         ax = total;
  282. if (debug) if(total) printf("select returns %d\n",total);
  283.         return;
  284.     case SI_IOCTL:
  285. if (debug) printf("ioctl called\n");
  286.         __sock[dx].bit.non_block = 1;
  287.         return;
  288.     case SI_CLOSE:
  289. if (debug) printf("close called\n");
  290.         __sock[dx].type = 0;
  291.         __sock[dx].bit.non_block = 0;
  292.         __sock[dx].bit.non_block_failed = 0;
  293.         __sock[dx].bit.is_connected = 0;
  294.         s = remove_array(dx);
  295.         sock_close(s);
  296.         ax = SUCCESS;
  297.         return;
  298.     case SI_SHUTDOWN:
  299. if (debug) printf("shutdown called\n");
  300.         if (init) tcp_shutdown();
  301.         init = 0;
  302.         break;
  303.     case SI_CHECKLOAD:
  304.         cx = 0x1234;
  305.         return;
  306.     };
  307. }
  308.  
  309. unreaddata(s)
  310. sock_type *s;
  311. {
  312.  
  313.     tcp_tick(s);
  314.     return(sock_dataready(s));
  315. }
  316.  
  317. sock_type *look_up(dx)
  318. int dx;
  319. {
  320.     int i;
  321.     for (i=0; i<MAX_SOCK; i++) {
  322.         if (sock_table[i] == dx) return(sock+i);
  323.     }
  324.     return(NULL);
  325. }
  326.  
  327. sock_type *remove_array(dx)
  328. int dx;
  329. {
  330.     int i;
  331.     for (i=0; i<MAX_SOCK; i++) {
  332.         if (sock_table[i] == dx) {
  333.             sock_table[i] = 0;
  334.             return(sock+i);
  335.         }
  336.     }
  337.     return(NULL);
  338. }
  339.  
  340. sock_type *new_array(dx, cx)
  341. int dx, cx;
  342. {
  343.     int i;
  344.     for (i=0; i<MAX_SOCK; i++) {
  345.         if (sock_table[i] == 0) {
  346.             sock_table[i] = dx;
  347.             sock_close(sock+i);/*just in case*/
  348.             return(sock+i);
  349.         }
  350.     }
  351.     return(NULL);
  352. }
  353. int main(void)
  354. {
  355.     union REGS regs;
  356.  
  357.     regs.x.ax = SI_CHECKLOAD;
  358.     int86(INTR,®s,®s);
  359.     if (regs.x.cx == 0x1234) {
  360.         fprintf(stderr,"Socket TSR is already loaded!\n");
  361.         exit(1);
  362.     }
  363.     oldhandler = getvect(INTR);
  364.     setvect(INTR, handler);
  365.     keep(0, (_SS + (_SP/16) - _psp) + 0x10);
  366.     return(0);
  367. }